/* CSci4061 S2010 Assignment 4
* section: 5, 2, 4
* login: korze015
* date: 04/19/10
*Names         :     Chris Korzenowski, William Dongoski, Franklin Okose
*ID's          :     3063772, 1863317, 3875511
*Test Machine  :     CS2170-12.itlabs.umn.edu 
*/

#include <pthread.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>


#define MAX 100
#define MAX_PATH 1024
#define MAX_FILE_SIZE 100000

char pathlife[MAX_PATH];

typedef struct work_args {
	int fd;
	char *content_type;
	char *buff;
	int numbytes;
}work_args;

typedef struct fetch_args {
	char *filename;
	char *guessed;
}fetch_args;

void *dispatch_loop(void *arg){
	int fd, fdes, nread;
	printf("in func\n");
	char *buf = (char*) arg;
	char file_type[MAX_PATH];
	char content[15];
	char findpath[MAX_PATH];
	
	while (1){
		printf("start loop while\n");
		fd = accept_connection();
		//printf("where's waldo\n");
		printf("fd = %d loging time sheets\n", fd);
		
		if (fd < 0)
			pthread_exit(NULL);
		else {
			
			if (get_request(fd, file_type) != 0){
				printf("get_request failed for fd %d with a file_type of %s\n", fd,file_type);
				continue;//Break??
			}
		} //need to somehow stop the connection on failure of get_request.
		
		if ((strstr(file_type, ".html")||(strstr(file_type, ".htm"))))
			strcpy(content,"text/html");
		else if (strstr(file_type, ".jpg"))
			strcpy(content,"image/jpeg");
		else if (strstr(file_type, ".gif"))
			strcpy(content,"image/gif");
		else
			strcpy(content,"text/plain");
			
		printf("guess my path?\n %s\n",pathlife);	
		strcpy(findpath, pathlife);	
		strcat(findpath,file_type);
		printf("guess my found path:\n %s\n",findpath);
		
		 fdes = open (findpath,  O_RDONLY|O_CREAT, 0666);	
		printf("where's waldo %s\n", findpath);
		nread = read(fdes,buf,MAX_FILE_SIZE);
		printf("he's in your socks\n");
			
		if (return_result(fd,content,buf,nread))
			if(return_error(fd,buf))
				printf("you have errors my friend\n");
		printf("end loop while\nlog after= %s\n",  file_type);
	}

}

void *worker_return(void *arg) {
	work_args *args = (work_args*) arg;
	return_result(args->fd, args->content_type, args->buff, args->numbytes);
	return_error(args->fd, args->buff);
}

void *prefetch_guesser(void *arg){
	fetch_args *args = (fetch_args *) arg;
	nextguess(args->filename, args->guessed);
}

int main(int argc, char *argv[]) {

	int fd, temp, made = 0;
	int *accept_conn_fd;
	int work_count = 0, disp_count = 0, q_count = 0, cache_count = 0; 
	char disp_buff[atoi(argv[3])][MAX_FILE_SIZE];
	struct work_args worker_arguments;
	struct fetch_args prefech_arguments;
		
	// setting up constants passed as arguments.
	int port = atoi(argv[1]);
	char *path = argv[2];
	int num_dispatch;
	int num_workers;
	int num_prefetch = 10;//determined in the assignment pdf
	int qlen;
	int caching = atoi(argv[6]);
	int cache_entries;
	
	if (argc < 8){
		printf("usage error: web_server_http port path num_dispatch num_workers qlen caching cache-entries/n");
		return 1;
	}
	strcpy(pathlife, argv[2]);
	
	printf("\n\n starfish %s %s\n", path, argv[2]);
	
	printf("temp = atoi(argv[3]);= %d", temp = atoi(argv[3]));
	if (temp <= MAX) 	
		{num_dispatch = temp;}
	else {
		printf("Maximum allowed is %d. Defaulting to %d.\n", MAX, MAX);
		{num_dispatch = MAX;}
	}
	temp = atoi(argv[4]);
	if (temp <= MAX) 	
		{num_workers = temp;}
	else {
		printf("Maximum allowed is %d. Defaulting to %d.\n", MAX, MAX);
		{num_workers = MAX;}
	}
	temp = atoi(argv[5]);
	if (temp <= MAX) 	
		{qlen = temp;}
	else {
		printf("Maximum allowed is %d. Defaulting to %d.\n", MAX, MAX);
		{qlen = MAX;}
	}
	
	temp = atoi(argv[7]);
	if (temp <= MAX) 	
		{cache_entries = temp;}
	else {
		printf("Maximum allowed is %d. Defaulting to %d.\n", MAX, MAX);
		{cache_entries = MAX;}
	}
	
	pthread_t work_threads[num_workers];
	pthread_t disp_threads[num_dispatch];
	pthread_t prefetch_threads[num_prefetch];
	pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
	pthread_cond_t  cond  = PTHREAD_COND_INITIALIZER;
	char addfile[10] = "log";
	fd = open("web_server_log", O_RDWR|O_CREAT, 0644);
	init(port);
	
	for(disp_count = 0; disp_count < num_dispatch ; disp_count++){
      printf("Creating dispatch thread %ld\n", disp_count);
	  //strcpy(disp_buff[disp_count], 
      made = pthread_create(&disp_threads[disp_count], NULL, dispatch_loop, (void *)disp_buff[disp_count]);
      if (made){
         printf("ERROR encountered in pthread_create(): %d\n", made);
         exit(-1);
      }
   }

 // need to populate worker_arguments otherwise blows up
  	for(work_count = 0; work_count < num_workers ; work_count++){
      printf("Creating worker thread %ld\n", work_count);
      made = pthread_create(&work_threads[work_count], NULL, dispatch_loop, (void *)disp_buff[disp_count]); //worker_return, (void *)&worker_arguments);
      if (made){
         printf("ERROR encountered in pthread_create(): %d\n", made);
         exit(-1);
      }
   }
	
	pthread_exit(NULL);
}
